package com.ashbur.rookie.user.controller;

import com.ashbur.rookie.api.BaseController;
import com.ashbur.rookie.api.controller.user.UserControllerApi;
import com.ashbur.rookie.common.grace.result.GraceJSONResult;
import com.ashbur.rookie.common.grace.result.ResponseStatusEnum;
import com.ashbur.rookie.common.utils.JsonUtils;
import com.ashbur.rookie.pojo.AppUser;
import com.ashbur.rookie.pojo.bo.UpdateUserInfoBO;
import com.ashbur.rookie.pojo.vo.AppUserVO;
import com.ashbur.rookie.pojo.vo.UserAccountInfoVO;
import com.ashbur.rookie.user.service.UserService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@RestController
//@DefaultProperties(defaultFallback = "defaultFallBack")
public class UserController extends BaseController implements UserControllerApi {

    final static Logger logger = LoggerFactory.getLogger(UserController.class);

    @Resource
    private UserService userService;

    @Value("${server.port}")
    private String myPort;

    public GraceJSONResult defaultFallBack(){
        logger.info("全局降级，进入到系统等待");
        return GraceJSONResult.errorCustom(ResponseStatusEnum.SYSTEM_ERROR_GLOBAL);
    }

    @Override
    public GraceJSONResult getAccountInfo(String userId) {

        // 0. 判断不能为空
        if (StringUtils.isBlank(userId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.UN_LOGIN);
        }

        // 1. 查询userId
        AppUser user = getUser(userId);

        // 2. 设置需要展示的信息
        UserAccountInfoVO accountVO = new UserAccountInfoVO();
        BeanUtils.copyProperties(user, accountVO);

        return GraceJSONResult.ok(accountVO);
    }
    @Override
    public GraceJSONResult updateUserInfo(UpdateUserInfoBO updateUserInfoBO) {
        // 执行更新用户信息操作
        // 1. 执行更新操作
        userService.updateUserInfo(updateUserInfoBO);
        return GraceJSONResult.ok();
    }


    @HystrixCommand//(fallbackMethod = "queryByIdsFullBack")
    @Override
    public GraceJSONResult queryByIds(String userIds) {
        // int a = 1 / 0;
        logger.info("today I choose this port {}",myPort);
        if (StringUtils.isBlank(userIds)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }

        List<AppUserVO> publisherList = new ArrayList<>();
        List<String> userIdList = JsonUtils.jsonToList(userIds, String.class);
        for (String uid : userIdList) {
            // 获得用户基本信息
            AppUserVO userVO = getBasicUserInfo(uid);
            // 添加到发布者list
            publisherList.add(userVO);
        }

        return GraceJSONResult.ok(publisherList);
    }
    public GraceJSONResult queryByIdsFullBack(String userIds) {
        logger.info("today I choose this port {}",myPort);
        // 手动触发异常
        logger.info("这里进入到降级的方法 full back methods here");
        List<AppUserVO> publisherList = new ArrayList<>();
        List<String> userIdList = JsonUtils.jsonToList(userIds, String.class);
        for (String uid : userIdList) {
            // 手动构建空对象，详情页所展示的用户信息在故障时，可有可无
            AppUserVO userVO = new AppUserVO();
            // 添加到发布者list
            publisherList.add(userVO);
        }
        return GraceJSONResult.ok(publisherList);
    }
    @Override
    public GraceJSONResult getUserInfo(String userId) {
        // 0. 判断参数不能为空
        if (StringUtils.isBlank(userId)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.UN_LOGIN);
        }

        // 1. 根据userId查询用户的信息
        AppUser user = getUser(userId);

        // 2. 返回用户信息
        AppUserVO userVO = new AppUserVO();
        BeanUtils.copyProperties(user, userVO);

        // 3. 查询用户的粉丝数，关注数
        // 3. 查询redis中用户的关注数和粉丝数，放入userVO到前端渲染
        userVO.setMyFansCounts(getCountsFromRedis(REDIS_WRITER_FANS_COUNTS + ":" + userId));
        userVO.setMyFollowCounts(getCountsFromRedis(REDIS_MY_FOLLOW_COUNTS + ":" + userId));


        return GraceJSONResult.ok(userVO);
    }


    /**
     * 获得用户基本信息
     * @return
     */
    private AppUserVO getBasicUserInfo(String userId) {
        // 1. 根据userId查询用户的信息
        AppUser user = getUser(userId);
        // 2. 返回用户信息
        AppUserVO userVO = new AppUserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    private AppUser getUser(String userId) {
        // 查询判断redis中是否包含用户信息，如果包含，则查询后直接返回，就不去查询数据库了
        String userJson = redis.get(REDIS_USER_INFO + ":" + userId);
        AppUser user = null;
        if (StringUtils.isNotBlank(userJson)) {
            user = JsonUtils.jsonToPojo(userJson, AppUser.class);
        } else {
            user = userService.getUser(userId);
            // 由于用户信息不怎么会变动，对于一些千万级别的网站来说，这类信息不会直接去查询数据库
            // 那么完全可以依靠redis，直接把查询后的数据存入到redis中
            redis.set(REDIS_USER_INFO + ":" + userId, JsonUtils.objectToJson(user));
        }
        return user;
    }


}
